#pragma once
#include <iostream>
#include <list>
// TODO: the base observer
struct Observer {
virtual void Update() = 0;// interface
virtual ~Observer() = default;
};


// TODO: the base class to be observed
struct Subject {
  // TODO: inject observer
  virtual void Attach(Observer* obser) = 0;
  virtual void Detach(Observer* obser) = 0;
  virtual void Notify() = 0;
  virtual ~Subject() = default;
};
// TODO: true subject to be observe
struct TobeCheckSubject : public Subject {
void Attach(Observer* obser) override {
  std::cout << "Attaching now" << std::endl;
  m_observers.push_back(obser);// push in queue
}
void Detach(Observer* obser) override {
  std::cout << "Detaching now" << std::endl;
  m_observers.remove(obser);
}
void Notify() override {
  for (auto obs: m_observers) {
    obs->Update();
  }
}

private:
std::list<Observer*> m_observers;
};

struct MoreClearObserver : public Observer {
void Update() override {
  std::cout << "[DEBUG]: calling [MoreClearObserver::Update()]" << std::endl;
}
};

struct MoreClearObserver2 : public Observer {
  void Update() override {
    std::cout << "[DEBUG]: calling [MoreClearObserver2::Update()]" << std::endl;
  }
};

